package com.hugh.commom.zk.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.hugh.commom.selector.ChannelFutureEntity;
import com.hugh.commom.selector.ChannelSelect;
import com.hugh.commom.zk.client.entity.ZkDataConfig;
import com.hugh.commom.zk.client.entity.ZkNodeEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: Hugh
 * @Date: 2020/6/23
 */
@Component
@Slf4j
public class ZkConfigHandle {

    private static Charset charset = Charset.forName("utf-8");

    @Autowired
    private CuratorFramework client;

//    @Autowired
//    private DataBaseConfig dataBaseConfig;

    public ZkDataConfig regist() throws Exception {

        ZkDataConfig zkDataConfig = ZkDataConfig.builder()
                .driverClassName("com.mysql.jdbc.Driver")
                .url("jdbc:mysql://localhost:3306/hugh")
                .passWorld("root")
                .userName("root")
                .build();
            // 创建节点
            String path = "/dbconfig";
            // 状态信息
            Stat stat = client.checkExists().forPath(path);
            if(Objects.nonNull(stat)) {
                byte[] bytes = client.getData().forPath(path);
                zkDataConfig = JSON.parseObject(new String(bytes), ZkDataConfig.class);
            }else{
                client.create().creatingParentsIfNeeded()
                        .withMode(CreateMode.EPHEMERAL).forPath(path, JSON.toJSONString(zkDataConfig).getBytes());
            }
            //订阅该节点
        ZKWatch zkWatch = new ZKWatch(path);
            byte[] data = client.
                getData().
                usingWatcher(zkWatch).forPath(path);
        log.info("监听节点数据变更" + path + " : " + new String(data, Charset.forName("utf-8")));

        return zkDataConfig;
    }


    /**
     * 添加监控
     */
    public class ZKWatch implements CuratorWatcher {

        private final String path;

        public ZKWatch(String path) {
            this.path = path;
        }

        @Override
        public void process(WatchedEvent event) throws Exception {
            List<ZkNodeEntity> znodeList = new ArrayList<>();
            // 状态信息
            Stat stat = client.checkExists().forPath(path);
            if(Objects.isNull(stat)) {
                client.create().creatingParentsIfNeeded()
                        .withMode(CreateMode.EPHEMERAL).forPath(path, JSON.toJSONString(znodeList).getBytes());
            }
            //继续订阅该节点
            byte[] data = client.
                    getData().
                    usingWatcher(this).forPath(path);
            log.info("监听节点数据变更" + path + " : " + new String(data, Charset.forName("utf-8")));
            //获取节点数据
            byte[] bytes = client.getData().forPath(path);
            ZkDataConfig zkDataConfig = JSON.parseObject(new String(bytes), ZkDataConfig.class);

            log.info("***重要***数据配置更新，更新类型是:{},更新信息是:{}", event.getType(), new String(data, Charset.forName("utf-8")));
        }
    }
}
